# Programm sortiert Bilder nach Erstellungsdatum und legt diese
# in erstellte Ordner folgender Struktur Jahr -> Monat -> Tag

###############################################################
import os
import time
import sys
import shutil
import exifread
###############################################################

def Num2Month(inVar):
    if inVar == "01":
        return "Jan"
    elif inVar == "02":
        return "Feb"
    elif inVar == "03":
        return "Mar"
    elif inVar == "04":
        return "Apr"
    elif inVar == "05":
        return "May"
    elif inVar == "06":
        return "Jun"
    elif inVar == "07":
        return "Jul"
    elif inVar == "08":
        return "Aug"
    elif inVar == "09":
        return "Sep"
    elif inVar == "10":
        return "Oct"
    elif inVar == "11":
        return "Nov"
    else:
        return "Dec"
    
def SortOutList(inList, fileType = "Image"): 
    
    retVar = []
    videoFileExtensions = ["avi", "mpg", "mpeg", "3gp", "mov", "mkv"]
    imgFileExtensions = ["jpg", "jpeg"]
    
    if fileType == "Image":
        extensions = imgFileExtensions
    elif fileType == "Video":
        extensions = videoFileExtensions
    
    for entry in inList:
        fileName = entry.split("\\")[-1]
        fileNameExt = fileName.split(".")[-1].lower()
        
        if fileNameExt in extensions:
            retVar.append(entry);
    
    return retVar

def DeleteEmptyFolder(path):
    
    fileList = os.listdir(path)
    
    # ist im Ordner was drin?
    if len(fileList) == 0:
        # wenn nein --> Ordner loeschen
        os.rmdir(path)
        
        # nur eine Datei "Thumbs.db"
    elif len(fileList) == 1 and fileList[0] == "Thumbs.db":
        os.remove(path + "\\Thumbs.db")
        os.rmdir(path)
        
    else:
        # sonst gehe liste durch und durchsuche jeden Ordner
        
        for name in fileList:
            nextPath = path + "\\" + name
    
            # Wenn Ordner
            if os.path.isdir(nextPath):
                # dann durchsuchen
                DeleteEmptyFolder(nextPath)
        
        # Liste bearbeitet -> versuch nochmal den Ordner zu loeschen
        fileList = os.listdir(path)
        if len(fileList) == 0:
            # wenn nein --> Ordner loeschen
            os.rmdir(path)
    return

def GetFileList(path): 
    retVar = []
    fileList = os.listdir(path)
    
    for name in fileList:
        datei = path + "\\" + name
    
        # Wenn Ordner
        if os.path.isdir(datei):
            
            # dann suche ihn durch
            result = GetFileList(datei)
            
            # wenn die Rueckgabeliste nicht leer ist
            if len(result) > 0:
                # gehe die Rueckgabe-Liste durch
                for resultEntry in result:
                
                    # und merke jeden Pfad
                    retVar.append(resultEntry);
        else:
            # sonst den pfad merken
            retVar.append(datei)
        
    
    return retVar


# Sammlungen
# os.access(path, mode)

# Aktuellen Pfad bestimmen

def GetVideoMetaData(videoFilePath):
    dateEntry = time.ctime(os.path.getmtime(videoFilePath))
    dateEntrySplit = dateEntry.split(" ")
    
    retVar = {}
    retVar['Year']  = dateEntrySplit[4]
    retVar['Month'] = dateEntrySplit[1]
    retVar['Day']   = str(int(dateEntrySplit[2]))
    
    return retVar

def GetImgMetaData(imgPath):
    f = open(imgPath, 'rb');
        
    try:
        tagname = 'EXIF DateTimeDigitized'
        tags = exifread.process_file(f, details=False, stop_tag=tagname)
        dateDigitized = tags[tagname]
    except:
        return {}   # mpty dictionary
        
    dateDigitizedSplit = dateDigitized.values.split(" ")
    creationDate =  dateDigitizedSplit[0]
    creationDateSplit = creationDate.split(":")
    f.close()
    retVar = {}
    retVar['Year']  = creationDateSplit[0]
    retVar['Month'] = Num2Month(creationDateSplit[1])
    retVar['Day']   = creationDateSplit[2]
    return retVar

def moveFile(path, entry, metaData):
    YearFolderPath  = path + "\\" + metaData['Year']
    MonthFolderPath = YearFolderPath  + "\\" + metaData['Month']
    DayFolderPath   = MonthFolderPath + "\\" + metaData['Day']
        
    if not os.path.exists(YearFolderPath):
        os.mkdir(YearFolderPath)
        
    if not os.path.exists(MonthFolderPath):
        os.mkdir(MonthFolderPath)
                
    if not os.path.exists(DayFolderPath):
        os.mkdir(DayFolderPath)
            
            
    destFileName = DayFolderPath + "\\" + entry.split("\\")[-1] 
        
    var = 1
    if os.path.exists(destFileName):
        var = 0
        try:
            os.remove(destFileName)
            var = 1
        except:
            print("Error at deleting existing file" + destFileName)
            print "Unexpected error:", sys.exc_info()[0]
                
    if var == 1:        
        shutil.move(entry, DayFolderPath)
    
    
def main():

    clockStart = time.clock()
    
    if len(sys.argv) == 1:
        path = os.getcwd()
    else:
        path = sys.argv[0]
    
    srcPath = path + "\Quelle"
    
    #srcPath = "D:/Alle Photos/Quelle"
    
    #path = "F:\Alle Photos"
    #srcPath = "F:\Alle Photos\Quelle"
    
    # Aktuellen pfad rekursiv nach Dateien durchsuchen und absolute pfade zur Dateien in Liste merken
    totalFileList = GetFileList(srcPath)
    print("Files found: " + str(len(totalFileList)))
    
    # Bilder aussortieren
    imgFileList = SortOutList(totalFileList, "Image")
    print("Image files found: " + str(len(imgFileList)))
    
    # Liste Videos aussortieren
    videoFileList = SortOutList(totalFileList, "Video")
    print("Video files found: " + str(len(videoFileList)))
    
    
    cnt = 0
    oldprogress = 0
    totalCnt = len(imgFileList) + len(videoFileList)
    
    # Bilder einsortieren
    for entry in imgFileList:
        # Aufnahmedatum bestimmen
        imgMetaData = GetImgMetaData(entry)
        
        if len(imgMetaData) == 0:
            continue
        
        moveFile(path, entry, imgMetaData)
        
        cnt += 1

        progress = float(cnt * 100) / float(totalCnt)
        progress = int(round(progress))
        
        if oldprogress != progress:
            print(str(progress) + " %")
            oldprogress = progress


    # Videos einsortieren        
    for entry in videoFileList:
        # Aufnahmedatum bestimmen
        videoMetaData = GetVideoMetaData(entry)
        
        if len(videoMetaData) == 0:
            continue
        
        moveFile(path, entry, videoMetaData)
        
        cnt += 1
        
        progress = float(cnt * 100) / float(totalCnt)
        progress = int(round(progress))
        
        if oldprogress != progress:
            print(str(progress) + " %")
            oldprogress = progress
        
    try:
        DeleteEmptyFolder(srcPath)
    except:
        print("Error at deleting empty folders")
        input("Press any key to end");
       
    
    clockEnd = time.clock()
    
    
    print('Ende! Dauer: ' + str(round((clockEnd - clockStart), 3)) + "s")
    time.sleep(3)



if __name__ == "__main__":
    main()
    